﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class LuaManager : Singleton<LuaManager>
{
    private LuaEnv m_LuaEnv;
    public LuaEnv LuaEnv
    {
        get
        {
            return m_LuaEnv;
        }
    }

    public bool m_bAssetBundle = true;
    private Dictionary<string, AssetBundle> m_dicAssetbundle = new Dictionary<string, AssetBundle>();

    public override void Initialize()
    {
        base.Initialize();
        if (!Application.isEditor || m_bAssetBundle)
        {
            LoadLuaFile("lua/framework.lua");
        }
        m_LuaEnv = new LuaEnv();
        InitLuaPath();  
        OpenLibs();
        LoadLuaMain();
    }

    void LoadLuaFile(string strFilePath)
    {
        strFilePath = strFilePath.ToLower();

        if (m_dicAssetbundle.ContainsKey(strFilePath))
        {
            return;
        }
        byte[] bytes = Utility.FileUtils.Instance().ReadFile(strFilePath);
        if (bytes == null || bytes.Length <= 0)
        {
            Utility.Log.Error("Load lua failed {0}", strFilePath);
            return;
        }

        AssetBundle ab = AssetBundle.LoadFromMemory(bytes);
        if (ab == null)
        {
            Utility.Log.Error("Load lua failed {0}", strFilePath);
            return;
        }
        Utility.Log.Trace("Load lua success {0}", strFilePath);
        m_dicAssetbundle.Add(strFilePath, ab);
        bytes = null;
    }

    void InitLuaPath()
    {
        m_LuaEnv.AddLoader((ref string filename) =>
        {
            byte[] readFile = null;
            if (m_bAssetBundle || !Application.isEditor)
            {
                // 打包lua文件时将路径“/”替换 为"_"作为文件名称了
                filename = filename.Replace("\\", "_").Replace("/", "_").Replace(".lua", "").ToLower();
                TextAsset tex = GetText(filename);
                if (tex != null)
                {
                    readFile = tex.bytes;
                }
                else
                {
                    Utility.Log.Error("Load Lua File Failed {0}", filename);
                }
            }
            else
            {
                //必须带后缀.lua
                string strFilePath = filename.EndsWith(".lua") ? filename : string.Format("{0}.lua", filename);
                strFilePath = strFilePath.Replace("\\", "/");
                readFile = System.IO.File.ReadAllBytes(Application.dataPath + "/" + strFilePath);
            }

            return readFile;
        });
    }

    TextAsset GetText(string strFilename)
    {
        foreach (AssetBundle ab in m_dicAssetbundle.Values)
        {
            TextAsset tex = ab.LoadAsset<TextAsset>(strFilename);
            if (tex != null)
            {
                return tex;
            }
        }
        return null;
    }

    void OpenLibs()
    {
        m_LuaEnv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);
    }

    void LoadLuaMain()
    {
        DOFile("LuaScripts/FrameWork/Main");
        System.Action func = m_LuaEnv.Global.Get<System.Action>("Main");
        if (func != null)
        {
            func();
            func = null;
        }
    }

    object[] DOFile(string filename)
    {
        byte[] readFile = null;

        if (!Application.isEditor || m_bAssetBundle)
        {
            filename = filename.Replace("\\", "_").Replace("/", "_").Replace(".lua", "").ToLower();

            TextAsset tex = GetText(filename);
            if (tex != null)
            {
                readFile = tex.bytes;
            }
            else
            {
                Utility.Log.Error("Load Lua File Failed {0}", filename);
            }

        }
        else
        {
            //必须带后缀.lua
            string strFilePath = filename.EndsWith(".lua") ? filename : string.Format("{0}.lua", filename);
            readFile = System.IO.File.ReadAllBytes(Application.dataPath + "/" + strFilePath);
        }

        if (m_LuaEnv != null && readFile != null)
        {
            object[] objs = m_LuaEnv.DoString(readFile, filename);
            //置空
            readFile = null;
            return objs;
        }
        return null;
    }

}
